/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	FactoryNativeScript.h
*
*	Description -	Factory for creating component native type scripts.
*
*	Comments	-
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	06/24/2013	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_FACTORY_NATIVE_SCRIPT_H_
#define _PSX_FACTORY_NATIVE_SCRIPT_H_

#include "PulseSTD.h"
#include "Singleton.h"
#include "ComponentNativeScript.h"
#include "StringID.h"
#include "Map.h"

#include "../External/FastDelegate/FastDelegate.h"

namespace Pulse
{

	typedef fastdelegate::FastDelegate1< ComponentNativeScript*, _INativeScript* > NativeScriptCreator;
	typedef fastdelegate::FastDelegate1< _INativeScript*, void > NativeScriptDeletor;

	class FactoryNativeScript : public Singleton<FactoryNativeScript>
	{
	public:

		~FactoryNativeScript( void );

		template < typename Function >
		void RegisterCreator( const StringIDValue id, Function &func );

		template < typename Function >
		void RegisterDeletor( const StringIDValue id, Function &func );

		BOOL RemoveCreator( const StringIDValue id );

		void ClearCreators( void );

		_INativeScript * Create( const StringIDValue id, ComponentNativeScript *pComponentScript );

		void Delete( _INativeScript *pScript );

	private:

		friend class Singleton<FactoryNativeScript>;

		FactoryNativeScript( void );

	private:

		typedef Map< StringIDValue, NativeScriptCreator > CreatorMap;
		typedef Map< StringIDValue, NativeScriptDeletor > DeletorMap;

		CreatorMap m_creators;
		DeletorMap m_deletors;

	};

	template < typename Function >
	void FactoryNativeScript::RegisterCreator( const StringIDValue id, Function &func )
	{
		auto findIter = m_creators.Find( id );

		if ( findIter != m_creators.IteratorEnd() )
		{
			PSX_PushWarning( "Creator type already registered." );
			return;
		}

		NativeScriptCreator creator( func );
		//creator.bind( func );

		m_creators[id] = creator;
	}

	template < typename Function >
	void FactoryNativeScript::RegisterDeletor( const StringIDValue id, Function &func )
	{
		auto findIter = m_deletors.Find( id );

		if ( findIter != m_deletors.IteratorEnd() )
		{
			PSX_PushWarning( "Deletor type already registered." );
			return;
		}

		NativeScriptDeletor deletor( func );
		//creator.bind( func );

		m_deletors[id] = deletor;
	}
}

#endif /* _PSX_FACTORY_NATIVE_SCRIPT_H_ */